/**
 * 验证码服务
 * 提供验证码生成、验证和管理功能
 */

const crypto = require('crypto');
const { Op } = require('sequelize');
const { logInfo, logError, logWarning } = require('../logger');
const VerificationCode = require('../models/VerificationCode');

/**
 * 生成随机验证码
 * @param {number} length - 验证码长度，默认6位
 * @returns {string} 生成的验证码
 */
const generateCode = (length = 6) => {
  return crypto.randomInt(100000, 999999).toString();
};

/**
 * 存储验证码
 * @param {string} email - 邮箱地址
 * @param {string} code - 验证码
 * @param {string} purpose - 用途(register/reset_password/change_email)
 * @param {number} expireMinutes - 过期时间（分钟），默认5分钟
 * @returns {Promise<Object>} 存储结果
 */
const storeCode = async (email, code, purpose = 'register', expireMinutes = 5) => {
  try {
    // 计算过期时间
    const expiresAt = new Date(Date.now() + expireMinutes * 60 * 1000);
    
    // 创建验证码记录
    const verificationCode = await VerificationCode.create({
      email,
      code,
      expiresAt,
      purpose
    });
    
    logInfo('验证码存储成功', { email, purpose });
    return { success: true, data: verificationCode };
  } catch (error) {
    logError('验证码存储失败', { error: error.message, email, code, purpose });
    return { success: false, error: error.message };
  }
};

/**
 * 验证验证码
 * @param {string} email - 邮箱地址
 * @param {string} code - 验证码
 * @param {string} purpose - 用途(register/reset_password/change_email)
 * @returns {Promise<Object>} 验证结果
 */
const verifyCode = async (email, code, purpose = 'register') => {
  try {
    // 查找验证码记录
    const verificationCode = await VerificationCode.findOne({
      where: {
        email,
        code,
        purpose,
        isUsed: false,
        expiresAt: {
          [Op.gt]: new Date()
        }
      }
    });
    
    if (!verificationCode) {
      logWarning('验证码验证失败：无效或已过期', { email, code, purpose });
      return { success: false, error: '验证码无效或已过期' };
    }
    
    // 标记验证码为已使用
    await verificationCode.update({ isUsed: true });
    
    logInfo('验证码验证成功', { email, purpose });
    return { success: true, data: verificationCode };
  } catch (error) {
    logError('验证码验证失败', { error: error.message, email, code, purpose });
    return { success: false, error: error.message };
  }
};

/**
 * 检查发送频率限制
 * @param {string} email - 邮箱地址
 * @param {number} seconds - 限制时间（秒），默认60秒
 * @returns {Promise<Object>} 检查结果
 */
const checkRateLimit = async (email, seconds = 10) => {
  try {
    // 计算时间范围
    const timeAgo = new Date(Date.now() - seconds * 1000);
    
    // 查找近期的验证码记录
    const recentCodes = await VerificationCode.count({
      where: {
        email,
        created_at: {
          [Op.gt]: timeAgo
        }
      }
    });
    
    // 如果近期有发送记录，则限制发送
    if (recentCodes > 0) {
      logWarning('验证码发送频率限制', { email, seconds });
      return { success: false, error: `请${seconds}秒后再试` };
    }
    
    return { success: true };
  } catch (error) {
    logError('验证码频率检查失败', { error: error.message, email });
    return { success: false, error: error.message };
  }
};

/**
 * 清理过期验证码
 * @returns {Promise<Object>} 清理结果
 */
const cleanExpiredCodes = async () => {
  try {
    // 删除过期且未使用的验证码
    const deletedCount = await VerificationCode.destroy({
      where: {
        isUsed: false,
        expiresAt: {
          [Op.lt]: new Date()
        }
      }
    });
    
    logInfo('过期验证码清理完成', { deletedCount });
    return { success: true, deletedCount };
  } catch (error) {
    logError('过期验证码清理失败', { error: error.message });
    return { success: false, error: error.message };
  }
};

module.exports = {
  generateCode,
  storeCode,
  verifyCode,
  checkRateLimit,
  cleanExpiredCodes
};